﻿#include "algorithm.h"

Algorithm::Algorithm()
{

}

// 滤波器
QVector<QPointF>  Algorithm::filter(const QVector<QPointF> &list, int type){

    int size = list.size();
    QVector<QPointF> res;

    if (type == 0){
        if(list.size() < 3){
            return list;
        }
        double coef = 1.0/3.0;


        res.append(QPointF(list[0].x(), list[0].y()*0.8 + list[1].y()*0.2));

        double t_value;
        for(int c = 1; c < size-1; c ++){
            t_value = list[c-1].y() * coef
                    + list[c].y()   * coef
                    + list[c+1].y() * coef;
            res.append(QPointF(list[c].x(), t_value));
        }

        res.append(QPointF(list[size-1].x(), list[size-1].y()*1 + list[size-2].y()*0));

    }

    if(type == 1){
        if(list.size() < 5){
            return list;
        }
        double t_value;
        t_value = list[0].y() * (+0.886)
                + list[1].y() * (+0.257)
                + list[2].y() * (-0.086)
                + list[3].y() * (-0.143)
                + list[4].y() * (+0.086);
        res.append(QPointF(list[0].x(), t_value));

        t_value = list[0].y() * (+0.257)
                + list[1].y() * (+0.371)
                + list[2].y() * (+0.343)
                + list[3].y() * (+0.171)
                + list[4].y() * (-0.143);
        res.append(QPointF(list[1].x(), t_value));

        for(int c = 2; c < size-2; c ++){
            t_value = list[c-2].y() * (-0.086)
                    + list[c-1].y() * (+0.343)
                    + list[ c ].y() * (+0.486)
                    + list[c+1].y() * (+0.343)
                    + list[c+2].y() * (-0.086);
            res.append(QPointF(list[c].x(), t_value));
        }

        t_value = list[size-5].y() * (-0.143)
                + list[size-4].y() * (+0.171)
                + list[size-3].y() * (+0.343)
                + list[size-2].y() * (+0.371)
                + list[size-1].y() * (+0.257);
        res.append(QPointF(list[size-2].x(), t_value));

        t_value = list[size-5].y() * (+0.086)
                + list[size-4].y() * (-0.143)
                + list[size-3].y() * (-0.086)
                + list[size-2].y() * (+0.257)
                + list[size-1].y() * (+0.886);
        res.append(QPointF(list[size-1].x(), t_value));
    }
    return res;
}

double Algorithm::linearFitting(const QVector<QPointF>& list, double* k, double* b)
{
    float sum_x2 = 0.0;
    float sum_y = 0.0;
    float sum_x = 0.0;
    float sum_xy = 0.0;

    int num = list.size();

    int i;
    for (i = 0; i < num; ++i)
    {
        sum_x2 += list[i].x() * list[i].x();
        sum_y += list[i].y();
        sum_x += list[i].x();
        sum_xy += list[i].x() * list[i].y();
    }


    float tmp = num * sum_x2 - sum_x * sum_x;
    if (abs(tmp) > 0.000001f){
        *k = (num * sum_xy - sum_x * sum_y) / tmp;
        *b = (sum_x2 * sum_y - sum_x * sum_xy) / tmp;
    }else{
        *k = 0;
        *b = 0;
        return -1;
    }

    // 返回偏差平均值
    double stderror = 0;
    for(int i = 0; i < num; i ++){
        stderror += pow(- ((list[i].x()*(*k) - list[i].y() + (*b)) / sqrt((*k)*(*k)+1)), 2);
    }
    return sqrt(stderror/num);

}

